/*
 * @Author: your name
 * @Date: 2021-09-06 15:16:52
 * @LastEditTime: 2021-09-16 15:06:57
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \datadome\src\ntils\Request.ts
 */

// vue3+ts 二次封装Axios

import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, AxiosError } from 'axios'
import { GetLocalStrong, useMassage } from './hooks'
import { router } from '../router/index'
import axios from 'axios'
import { Modal } from 'ant-design-vue'
import qs from 'qs'

import { CreateAxiosOptions } from './types'

let { createMessage, createModalerror } = useMassage()

export class RequestAxios<RequestType> {
    private axiosInstance: AxiosInstance

    private readonly options: CreateAxiosOptions

    constructor(options:CreateAxiosOptions) {
        // 默认参数 
        this.options = options
        // 创建axios  
        this.axiosInstance = axios.create(options)
        this.setupInterceptors()
    }

    // 拦截器
    setupInterceptors() {
        this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
            let Authorization = GetLocalStrong('roles')
            // 检测登录未登录给出弹窗并跳转到login
            if (!Authorization) {
                createModalerror({
                    title: '警告',
                    content: '你尚未登录或者登录状态已经失效，请重新登录',
                    onOk: (e) => {
                        setTimeout(() => {
                            Modal.destroyAll()
                            router.push('/login')
                        }, 10)
                    },
                })
                //  未登录
                // createMessage.warn('未登录') 
            }
            // 序列化之后请求头需要填写application/x-www-form-urlencoded
            config.headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
            }   
            return config
        })
        this.axiosInstance.interceptors.response.use((res) => res, err => {
            createMessage.warn('网络错误') 
        })
    }

    // GET
    get<T = any>(config: AxiosRequestConfig):Promise<T> {
        return this.request({ ...config, method: 'GET' })
    }
  
    // POST
    post<T = any>(config: AxiosRequestConfig):Promise<T> {
        return this.request({ ...config, method: 'POST' })
    }
 
    // PUT 
    put<T = any>(config: AxiosRequestConfig):Promise<T> {
        return this.request({ ...config, method: 'PUT' })
    }
  
    // DELETE
    delete<T = any>(config: AxiosRequestConfig):Promise<T> {
        return this.request({ ...config, method: 'DELETE' })
    }
  
    // 请求
    request<T = any>(config: AxiosRequestConfig):Promise<T> {
        let conf: CreateAxiosOptions = config
        conf = this.urlFordata(conf)
        return new Promise((resolve, reject) => {
            this.axiosInstance
            .request<any, AxiosResponse>(conf)
            .then((res:AxiosResponse) => {
                if (!res) {
                    createMessage.warn('请求错误')  
                }
                resolve(res)  
            })
            .catch((err:AxiosError) => {
                console.log(err)
                reject(err)
            })
        })
    }

    // post 需要参数序列化，GET请求不用处理
    urlFordata(config: AxiosRequestConfig) {
        if (config.method?.toUpperCase() == 'GET') {
            return config
        }
        return {
            ...config,
            data: qs.stringify(config.data), 
        }
    }   
}

// 测速通道--为了不影响页面性能 暂时 不启用测试通道测试网速
export function InternetSpeed(url):void {
    let startTime, endTime, fileSize, Speed
    let xhr = new XMLHttpRequest()
    xhr.onreadystatechange = () => {
        if (xhr.readyState === 2) {
            startTime = Date.now()
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            endTime = Date.now()
            fileSize = xhr.responseText.length
            let speed = (fileSize) / 1024 / (endTime - startTime)
            console.log(speed, (endTime - startTime))
        }
    }
    xhr.open('GET', url, true)
    xhr.send() 
}
window.addEventListener('offline', () => {
    createMessage.warn('网络断开')
})
window.addEventListener('online', () => {
    createMessage.success('网络已链接')
})